using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

using System.IO;
using System.IO.Compression;

public partial class CompressionTools
{
    // Setting function characteristics
    [Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, DataAccess = DataAccessKind.None)]

    public static SqlBytes Compress(SqlBytes blob)
    {
        if (blob.IsNull)
            return blob;

        // Retrieving BLOB data
        byte[] blobByte = blob.Buffer;

        // Preparing for compression
        MemoryStream ms = new MemoryStream();
        DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress, true);

        // Writting uncompressed data using a DeflateStream ds
        ds.Write(blobByte, 0, blobByte.Length);

        // Clossing ds to allow ALL compressed bytes to be written
        ds.Flush();
        ds.Close();
        ds = null;

        // Returning compressed blob
        return new SqlBytes(ms);
    }


    public static SqlBytes Decompress(SqlBytes blob)
    {
        if (blob.IsNull)
            return null;

        // Preparing to read data from compressed stream
        DeflateStream ds = new DeflateStream(blob.Stream, CompressionMode.Decompress, true);

        // Initializing variables
        int byteCount = 1;
        byte[] byteBuffer = new byte[10000];

        // Preparing destination stream to hold decompressed data
        MemoryStream ms = new MemoryStream();

        try
        {
            // Reading from compressed stream 
            while ((byteCount = ds.Read(byteBuffer, 0, 10000)) > 0)
            {
                // Writting decompressed data
                ms.Write(byteBuffer, 0, byteCount);
            }
        }
        catch (Exception)
        {
            throw; // Nothing to do...
        }
        finally
        {
            // Cleaning up
            ds.Close();
            ds = null;
        }

        // Returning a decompressed BLOB
        return new SqlBytes(ms);
    }


};
